﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using JEng_Mark_1.GameComponents;
using JEng_Mark_1.Managers;
using JEng_Mark_1.GUI;

namespace JEng_Mark_1.GameComponents
{
    public class JDropConsole : JGameScreen
    {
        private static int _messagesToShow = 10;

        /// <summary>
        /// The number of lines the console will show at once
        /// </summary>
        public static int MessagesToShow { get { return _messagesToShow; } set { _messagesToShow = value; } }

        private static Vector2 _borderPadding = new Vector2(10, 10);

        /// <summary>
        /// The spacing on all sides of the text in the console
        /// </summary>
        public static Vector2 BorderPadding { get { return _borderPadding; } set { _borderPadding = value; } }

        private static float _linePadding = 3.0f;

        /// <summary>
        /// The spacing between lines of text in the console
        /// </summary>
        public static float LinePadding { get { return _linePadding; } set { _linePadding = value; } }

        private static Color _fontColor = Color.White;

        /// <summary>
        /// The color of the console text
        /// </summary>
        public static Color FontColor { get { return _fontColor; } set { _fontColor = value; } }

        private static Color _errorColor = Color.Red;

        /// <summary>
        /// The color of the console text for error messages
        /// </summary>
        public static Color ErrorColor { get { return _errorColor; } set { _errorColor = value; } }

        private static JGPanel _panel = null;

        public static JGPanel GUIPanel { get { return _panel; } set { _panel = value; } }

        private SpriteFont _font;
        private string _fontPath;

        /// <summary>
        /// Construct a new drop console and set transition times
        /// </summary>
        public JDropConsole(string fontPath) 
        {
            TransitionTime = TimeSpan.FromSeconds(1.0f);
            TransitionOffTime = TimeSpan.FromSeconds(1.0f);
            IsPopup = true;
            //remember font location for loading later
            _fontPath = fontPath;
        }

        public override void LoadContent()
        {
            base.LoadContent();

            //load console font
            _font = JEngineManager.ContentManager.Load<SpriteFont>(_fontPath);
            //Load any gui content
        }

        public override void UnloadContent()
        {
            base.UnloadContent();

            //Unload any gui content
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }

        public override void Draw(GameTime gameTime)
        {
            //Darken everything but the console
            JScreenManager.FadeBackBufferToBlack(TransitionAlpha * 2 / 3);

            //we only need height so using a static string is fine
            Vector2 lineSize = _font.MeasureString("test string");

            //calculate console size
            float height = (MessagesToShow * (lineSize.Y + LinePadding)) + (2 * BorderPadding.Y);
            Rectangle rect = new Rectangle(0, 0,
                JEngineManager.Device.Viewport.Width,
                (int)height);

            //set the background panel size
            GUIPanel.ObjectRect = rect;
            GUIPanel.Show = true;

            JLogEntry[] lines = JLog.getLastMessages(MessagesToShow);


            //draw the background and all console text
            if (_panel != null)
                _panel.Draw();

            SpriteBatch sb = JScreenManager.SpriteBatch;
            sb.Begin();
            for (int i = 0; i < MessagesToShow; i++)
            {
                Color dC = FontColor;
                if (lines[i].IsError) dC = ErrorColor;
                Vector2 textPosition = CalculateTextPosition(i,lineSize.Y);
                sb.DrawString(_font, lines[i].ToString(), textPosition, dC);
            }
            sb.End();
        }

        /// <summary>
        /// Helper function to place lines of text in the console
        /// </summary>
        /// <param name="index">Line count of this message</param>
        /// <param name="lineHeight">Height in pixels of each line</param>
        /// <returns>Position to place this line of text at</returns>
        private Vector2 CalculateTextPosition(int index, float lineHeight)
        {
            Vector2 pos = new Vector2(BorderPadding.X, BorderPadding.Y);
            int lineOffset = (int)(index * (lineHeight + LinePadding));
            pos.Y += lineOffset;
            return pos;
        }

        public override void HandleInput(JInput input)
        {
            //check if we need to close the console
            if (input.IsNewKeyPress(Microsoft.Xna.Framework.Input.Keys.OemTilde))
            {
                this.ExitScreen();
            }
        }
    }
}
